﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using PdfSharp.Fonts;

namespace WpfUsercontrol.Utils.Pdf
{
    public class SimFontResolver : IFontResolver
    {
        /// <summary>
        /// 字体作为嵌入资源所在程序集
        /// </summary>
        public static string FontAssemblyString { get; set; } = "WpfUsercontrol";
        /// <summary>
        /// 字体作为嵌入资源所在命名空间
        /// </summary>
        public static string FontNamespace { get; set; } = "WpfUsercontrol.Utils.Pdf.Fonts";

        /// <summary>
        /// 字体名称
        /// </summary>
        public static class FamilyNames
        {
            // This implementation considers each font face as its own family.
            /// <summary>
            /// 仿宋
            /// </summary>
            public const string SIMFANG = "simfang.ttf";
            /// <summary>
            /// 黑体
            /// </summary>
            public const string SIMHEI = "simhei.ttf";
            /// <summary>
            /// 楷书
            /// </summary>
            public const string SIMKAI = "simkai.ttf";
            /// <summary>
            /// 隶书
            /// </summary>
            public const string SIMLI = "simli.ttf";
            /// <summary>
            /// 宋体
            /// </summary>
            public const string SIMSUN = "simsun.ttf";
            /// <summary>
            /// 宋体加粗
            /// </summary>
            public const string SIMSUNB = "simsunb.ttf";
            /// <summary>
            /// 幼圆
            /// </summary>
            public const string SIMYOU = "simyou.ttf";
        }


        /// <summary>
        /// Selects a physical font face based on the specified information
        /// of a required typeface.
        /// </summary>
        /// <param name="familyName">Name of the font family.</param>
        /// <param name="isBold">Set to <c>true</c> when a bold font face
        ///  is required.</param>
        /// <param name="isItalic">Set to <c>true</c> when an italic font face 
        /// is required.</param>
        /// <returns>
        /// Information about the physical font, or null if the request cannot be satisfied.
        /// </returns>
        public FontResolverInfo? ResolveTypeface(string familyName, bool isBold, bool isItalic)
        {
            // Note: PDFsharp calls ResolveTypeface only once for each unique combination
            // of familyName, isBold, and isItalic. 

            return new FontResolverInfo(familyName, isBold, isItalic);
            // Return null means that the typeface cannot be resolved and PDFsharp forwards
            // the typeface request depending on PDFsharp build flavor and operating system.
            // Alternatively forward call to PlatformFontResolver.
            //return PlatformFontResolver.ResolveTypeface(familyName, isBold, isItalic);
        }

        /// <summary>
        /// Gets the bytes of a physical font face with specified face name.
        /// </summary>
        /// <param name="faceName">A face name previously retrieved by ResolveTypeface.</param>
        /// <returns>
        /// The bits of the font.
        /// </returns>
        public byte[]? GetFont(string faceName)
        {
            //// Note: PDFsharp never calls GetFont twice with the same face name.
            //// Note: If a typeface is resolved by the PlatformFontResolver.ResolveTypeface
            ////       you never come here.
            //var name = $"{FontNamespace}.{faceName}";
            //using Stream stream = Assembly.Load(FontAssemblyString).GetManifestResourceStream(name) ?? throw new ArgumentException("No resource named '" + name + "'.");
            //int num = (int)stream.Length;
            //byte[] array = new byte[num];
            //stream.Read(array, 0, num);
            //// Return the bytes of a font.
            //return array;


            var name = $"{FontNamespace}.{faceName}";

            // 尝试加载指定字体
            using Stream stream = Assembly.Load(FontAssemblyString).GetManifestResourceStream(name);
            if (stream != null)
            {
                int num = (int)stream.Length;
                byte[] array = new byte[num];
                stream.Read(array, 0, num);
                return array;
            }

            // ⚠️ 字体未找到，回退到默认字体（例如 Arial）
            const string defaultFontName = FamilyNames.SIMHEI; // 或你嵌入的其他默认字体，如 "LiberationSans"
            var defaultName = $"{FontNamespace}.{defaultFontName}";

            using Stream defaultStream = Assembly.Load(FontAssemblyString).GetManifestResourceStream(defaultName);
            if (defaultStream != null)
            {
                int num = (int)defaultStream.Length;
                byte[] array = new byte[num];
                defaultStream.Read(array, 0, num);
                return array;
            }

            // 🚨 连默认字体都找不到（严重错误），可抛异常或返回硬编码的备用方案
            throw new InvalidOperationException($"字体 '{faceName}' 和默认字体 '{defaultFontName}' 均未在嵌入资源中找到。请确保字体已正确嵌入。");
        }
    }
}
